package body FSIO is 

    procedure Parser (Path : in String) is
    	Separators : constant String := " " & ASCII.LF & ASCII.CR & ASCII.HT;
    	Session : Session_Type;
    begin
    	Set_Current(Session);
    	Open (Separators, Path);
    	
    	while not End_Of_File loop
    		Get_Line; Callback;
		end loop;
		
		Close(Session);
    end Parser;

    procedure Charger_Commandes (Path : in String;
                                 Liste_Comm : in out Liste_Commandes.T_Liste) is
        procedure Traiter is
        	Etat : Commandes.Etat_Commande;
        	Id : Natural := Field(1);
        	Client : String(1..4) := Field(2);
        	Verre : Categorie_Verre := Str_To_Char(Field(3));
        	Largeur : Natural := Field(4);
        	Hauteur : Natural := Field(5);
        begin
        	Etat := Commandes.Verifier (Verre, Largeur, Hauteur);
        	
        	if Etat /= 'A' then
        		Liste_Commandes.Ajouter(Liste_Comm, Commandes.Creer (Id, Client, Etat));
        	else
    			Liste_Commandes.Ajouter(Liste_Comm, Commandes.Creer (Id, Client, Verre,
													 			 Dim(Largeur,Hauteur)));
			end if;
		end Traiter;
        
    	procedure Charger is new Parser (Traiter);
    begin
		Charger(Path);
	exception
        when GNAT.AWK.FILE_ERROR => Text_Io.Put("Le fichier " & Path & " n'existe pas !");    
    end Charger_Commandes;
	
	procedure Sauver_Plan_Decoupe (Path : in String; L : in Liste_Plaques_Finales.T_Liste) is
        Fichier : Text_Io.File_Type;
    	
    	procedure Analyser_Plaque (P : in Plaques_Finales.Plaque_Finale) is
    		procedure Analyser_Piece (Pi : in Pieces.Piece) is
    			Pos_Pi : Dimension := Emplacements.Get_Position((Pieces.Get_Emplacement(Pi)));
    		begin
    			Put_Natural(Fichier, Pieces.Get_Id_Comm(Pi), 7);
    			Text_Io.Put(Fichier, " (");
    			Put_Natural(Fichier, Get_Largeur(Pos_Pi));
    			Text_Io.Put(Fichier, ",");
    			Put_Natural(Fichier, Get_Hauteur(Pos_Pi));
    			Text_Io.Put_Line(Fichier, ")");
    		end Analyser_Piece;
    		
    		procedure Ecrire_Contenu_Plaque is new Plaques_Finales.Liste.Foreach(Analyser_Piece);
    	
    	begin
    		Text_Io.Put(Fichier, "<" & Plaques_Finales.Get_Verre(P) & ",");
    		Put_Natural(Fichier, Plaques_Finales.Get_Id(P));
    		Text_Io.Put_Line(Fichier, ">");
    		Ecrire_Contenu_Plaque(Plaques_Finales.Get_Contenu(P));
    		Text_Io.Put(Fichier,"surface_chutes");
    		Put_Natural(Fichier, Plaques_Finales.Get_Surface_Chutes(P), 10);
    		Text_Io.Put(Fichier," Tx ");
    		Real_Io.Put(Fichier, Plaques_Finales.Taux_Remplissage(P), Fore=>2, Aft=>2, Exp=>0);
    		Text_Io.New_Line(Fichier);
    		Text_Io.Put_Line(Fichier, "---------------");
    	end Analyser_Plaque;
    	
    	procedure Ecrire_Plan is new Liste_Plaques_Finales.Liste.Foreach(Analyser_Plaque);
	begin
        Text_Io.Create(File => Fichier,
                       Mode => Text_Io.Out_File,
                       Name => Path);
        
        Ecrire_Plan(L);
        
        Text_Io.Close(Fichier);
    end Sauver_Plan_Decoupe;
        	

	procedure Sauver_Plaques_XML (Path : in String; L : in Liste_Plaques_Finales.T_Liste) is
        Fichier : Text_Io.File_Type;
    	N : Natural := 0;
    	
    	procedure Analyser_Plaque (P : in Plaques_Finales.Plaque_Finale) is
    		procedure Analyser_Piece (Pi : in Pieces.Piece) is
    			Pos_Pi : Dimension := Emplacements.Get_Position((Pieces.Get_Emplacement(Pi)));
    		begin
    			Text_Io.Put(Fichier, ASCII.HT & ASCII.HT & "<piece id='");
    			Put_Natural(Fichier, Pieces.Get_Id_Comm(Pi));
    			Text_Io.Put(Fichier, "' posx='");
    			Put_Natural(Fichier, Get_Largeur(Pos_Pi));
    			Text_Io.Put(Fichier, "' posy='");
    			Put_Natural(Fichier, Get_Hauteur(Pos_Pi));
    			Text_Io.Put(Fichier, "' largeur='");
    			Put_Natural(Fichier, Get_Largeur(Pieces.Get_Dimension(Pi)));
    			Text_Io.Put(Fichier, "' hauteur='");
    			Put_Natural(Fichier, Get_Hauteur(Pieces.Get_Dimension(Pi)));
    			Text_Io.Put_Line(Fichier, "' />");
    			
    			
    		end Analyser_Piece;
    		
    		procedure Ecrire_Contenu_Plaque is new Plaques_Finales.Liste.Foreach(Analyser_Piece);
    		
    	begin
    		Text_Io.Put(Fichier, ASCII.HT & "<plaque verre='" & Plaques_Finales.Get_Verre(P) & "' id='");
    		Put_Natural(Fichier, Plaques_Finales.Get_Id(P));
    		Text_Io.Put(Fichier, "' largeur='");
    		Put_Natural(Fichier, Get_Largeur(Plaques_Finales.Get_Taille(P)));
    		Text_Io.Put(Fichier, "' hauteur='");
    		Put_Natural(Fichier, Get_Hauteur(Plaques_Finales.Get_Taille(P)));
    		Text_Io.Put(Fichier, "' taux='");
    		Put_Natural(Fichier, Natural(Plaques_Finales.Taux_Remplissage(P)));
    		Text_Io.Put_Line(Fichier, "'>");
    		Ecrire_Contenu_Plaque(Plaques_Finales.Get_Contenu(P));
    		Text_Io.Put_Line(Fichier, ASCII.HT & "</plaque>");
    		
    		N := N+1;
    	end Analyser_Plaque;
    	
    	procedure Ecrire_Plan is new Liste_Plaques_Finales.Liste.Foreach(Analyser_Plaque);
	begin
		null;
        Text_Io.Create(File => Fichier,
                       Mode => Text_Io.Out_File,
                       Name => Path);
        Text_Io.Put_Line(Fichier, "<?xml version='1.0' encoding='ISO-8859-1'?>");
        Text_Io.Put_Line(Fichier, "<?xml-stylesheet type='text/xsl' href='plandecoupe_svg.xsl'?>");
        
        Text_Io.Put_Line(Fichier, "<plan>");
        Ecrire_Plan(L);
        Text_Io.Put_Line(Fichier, "</plan>");

        Text_Io.Close(Fichier);
    end Sauver_Plaques_XML;

	procedure Sauver_Commandes (Path : in String; Liste_Comm : in out Liste_Commandes.T_Liste) is
        Fichier : Text_Io.File_Type;
        Espace : Character := ' ';
        
     	procedure Ecrire_Comm_Erronee (Comm : in Commandes.Commande) is
     	begin
	     	Int_Io.Put(Fichier, Commandes.Get_Id(Comm), 7);
	     	Text_Io.Put(Fichier, " E ");
			Text_Io.Put(Fichier, Commandes.Get_Etat(Comm));
			Text_Io.New_Line(Fichier);
		end Ecrire_Comm_Erronee;

     	procedure Ecrire_Comm_Attente (Comm : in Commandes.Commande) is
     	begin
	     	Int_Io.Put(Fichier, Commandes.Get_Id(Comm), 7);
	     	Text_Io.Put(Fichier, " A ");
			Text_Io.New_Line(Fichier);
		end Ecrire_Comm_Attente;

     	procedure Ecrire_Comm_Satisfaite (Comm : in Commandes.Commande) is
     	begin
	     	Int_Io.Put(Fichier, Commandes.Get_Id(Comm), 7);
	     	Text_Io.Put(Fichier, " S ");
	     	
	     	Text_Io.Put(Fichier,Categories.Get_Categorie_Verre(Pieces.Get_Categorie(Commandes.Get_Piece_Assoc(Comm))));
	     	Int_Io.Put(Fichier,Emplacements.Get_Id_Plaque(Pieces.Get_Emplacement(Commandes.Get_Piece_Assoc(Comm))),7);
	     	Int_Io.Put(Fichier,Get_Largeur(Emplacements.Get_Position(Pieces.Get_Emplacement(Commandes.Get_Piece_Assoc(Comm)))),5);
	     	Int_Io.Put(Fichier,Get_Hauteur(Emplacements.Get_Position(Pieces.Get_Emplacement(Commandes.Get_Piece_Assoc(Comm)))),5);
	     	
			Text_Io.New_Line(Fichier);
	    end Ecrire_Comm_Satisfaite; 	

		-- Optimiser
		procedure Ecrire_Ligne (Comm : in Commandes.Commande) is
		begin
			if Commandes.Get_Etat(Comm) = 'A' then
				Ecrire_Comm_Attente (Comm);
			elsif Commandes.Get_Etat(Comm) = 'S' then
				Ecrire_Comm_Satisfaite (Comm);
			else
				Ecrire_Comm_Erronee(Comm);
			end if;
		end Ecrire_Ligne;
		
		
		procedure Ecrire_Tout is new Liste_Commandes.Liste.Foreach(Ecrire_Ligne);

	begin
        Text_Io.Create(File => Fichier,
                       Mode => Text_Io.Out_File,
                       Name => Path);	
		Ecrire_Tout(Liste_Comm);
		
        Text_Io.Close(Fichier);	
	end Sauver_Commandes;

--    procedure Sauver_Commandes_Triees (Path : in String; Liste_Comm : in out Liste_Commandes.T_Liste) is
--        Fichier : Text_Io.File_Type;
--        
--        Id: Natural;
--        Espace : Character := ' ';
--        Largeur : Natural;
--        Hauteur : Natural;
--        
--        procedure Ecrire_Ligne (Comm : in out Commandes.Commande) is
--            use Commandes; use Pieces;
--        begin
--            Id := Get_Id(Comm);
--            Int_Io.Put(Fichier, Id, Natural'Image(Id)'Length - 1);
--            Text_Io.Put(Fichier, Espace);
--            Text_Io.Put(Fichier, Get_Client(Comm));
--            Text_Io.Put(Fichier, Espace);
--            Text_Io.Put(Fichier, Categories.Get_Categorie_Verre(Get_Categorie(Get_Piece_Assoc(Comm)).all));
--            Text_Io.Put(Fichier, Espace);
--            Largeur := Get_Largeur(Get_Dimension(Get_Piece_Assoc(Comm)));
--            Int_Io.Put(Fichier, Largeur, Natural'Image(Largeur)'Length - 1);
--            Text_Io.Put(Fichier, Espace);
--            Hauteur := Get_Hauteur(Get_Dimension(Get_Piece_Assoc(Comm)));
--            Int_Io.Put(Fichier, Hauteur, Natural'Image(Hauteur)'Length - 1);
--            Text_Io.new_line(Fichier);
--        end Ecrire_Ligne;
--        
--        procedure Ecrire_Liste is new Liste_Commandes.Liste.Map(Ecrire_Ligne);
--    begin
--        Text_Io.Create(File => Fichier,
--                       Mode => Text_Io.Out_File,
--                       Name => Path);
--        
--        Ecrire_Liste(Liste_Comm);
--    
--    end Sauver_Commandes_Triees;

     procedure Sauver_Commandes_Clients (Path : in String; Liste_Comm : in out Liste_Commandes.T_Liste) is
        Fichier : Text_Io.File_Type;
        Espace : Character := ' ';
        Client : String(1..4) := "    ";
        procedure Ecrire_Commande (Comm : in Commandes.Commande) is
        begin 
           Put_Natural(Fichier, Commandes.Get_Id(Comm), 7);
           Text_Io.Put(Fichier, " ");           
           Text_Io.Put(Fichier, Categories.Get_Categorie_Verre(Pieces.Get_Categorie(Commandes.Get_Piece_Assoc(Comm))));
           Text_Io.Put(Fichier, " (");
 	       Put_Natural(Fichier, Get_Largeur(Pieces.Get_Dimension(Commandes.Get_Piece_Assoc(Comm))));
 	       Text_Io.Put(Fichier, ",");
      	   Put_Natural(Fichier, Get_Hauteur(Pieces.Get_Dimension(Commandes.Get_Piece_Assoc(Comm))));
           Text_Io.Put_Line(Fichier, ")");                
        end Ecrire_Commande; 
      
      procedure Ecrire_Client (Comm : in Commandes.Commande) is   
      begin
            if (Client /= Commandes.Get_Client(Comm)) then
            Text_Io.Put(Fichier, "--" & Commandes.Get_Client(Comm) & "--");
            Client := Commandes.Get_Client(Comm);
            Text_Io.New_Line(Fichier);
            end if;
            Ecrire_Commande (Comm); 
      end Ecrire_Client ;
      
      procedure Ecrire_Tout is new Liste_Commandes.Liste.Foreach(Ecrire_Client);
      
   begin
      Liste_Commandes.Trier_Par_Client(Liste_Comm); 
      Text_Io.Create(File => Fichier,
              Mode => Text_Io.Out_File,
              Name => Path);	
	 Ecrire_Tout(Liste_Comm);
	 
	 Text_Io.Close(Fichier);              
   end Sauver_Commandes_Clients;

    procedure Charger_Donnees_Generales (Path : in String) is
        procedure Traiter is
        begin            
            Liste_Categories.Ajouter(Categories.Creer(Str_To_Char(Field(1)), 
                                                     Dim_Piece_Mini => Dim(Field(4), Field(5)),
                                                     Taille_Plaque => Dim(Field(2), Field(3)))); 
													 			 
		end Traiter;
        
    	procedure Charger is new Parser (Traiter);
    begin
     	Liste_Categories.Init;
		Charger(Path);    
    end Charger_Donnees_Generales;


    procedure Charger_Stock (Path : in String; Stock : in out Liste_Plaques.T_Liste) is
        procedure Traiter is
        begin            
			Liste_Plaques.Ajouter(Stock, Plaques.Creer(Field(2), Str_To_Char(Field(1))));							 			 
		end Traiter;
        
   	procedure Charger is new Parser (Traiter);
    begin
        Liste_Plaques.Vider(Stock);
		Charger(Path);
		Liste_Plaques.Trier(Stock);    
    end Charger_Stock;

	procedure Put_Natural (File: in out Text_Io.File_Type; N : in Natural; Largeur : in Natural := 0) is
		Taille : Natural := Natural'Image(N)'Length;
	begin
		for I in 1..(Largeur - Taille + 1) loop
			Text_Io.Put(File, " ");
		end loop;
		Int_Io.Put(File, N, (Taille - 1));
	end Put_Natural;
end FSIO;

